/**
 * mongodb操作接口
 */

//引入Q模块
var Q = require('q');
//引入通用函数模块
var util = require('./util');
//引入mongodb模块的MongoClient
var mongo = require('mongodb').MongoClient;

//连接mongodb数据库函数
var connect = function(dbHost, dbPort, dbName, dbUser, dbPwd) {
	var deferred = Q.defer();
	//mongodb连接字符串
	var url = 'mongodb://' + dbUser + ':' + dbPwd + '@' + dbHost + ':' + dbPort + '/' + dbName;
	//连接函数
	mongo.connect(url, {authSource: 'admin'}, function(err, db) {
		if(err) {
			//连接错误
			console.log(err);
			deferred.reject();
		}
		else {
			//连接成功，将自定义的函数嵌入db实例中
			for(var funName in dbFuns) {
				db[funName] = dbFuns[funName];
			}
			//返回db实例
			deferred.resolve(db);
		}
	});
	return deferred.promise;
}

//mongodb数据库连接关闭函数
var close = function() {
	var deferred = Q.defer();
	//关闭连接
	this.close();
	deferred.resolve();
	return deferred.promise;
}

//mongodb数据库插入数据函数,data可以是包含多个对象的数组也可以是包含一个对象
var insert = function(table, data) {
	var deferred = Q.defer();
	//选中数据集合（表）
	var table = this.collection(table);
	//判断data是否是一个数组
	util.isArray(data).then(function() {
		//是一个包含对象的数组，将数组内的所有对象插入数据集合
		table.insertMany(data, function(err, res) {
			if(err) {
				//插入失败
				console.log(err);
				deferred.reject();
			}
			else {
				//插入成功返回影响行数1
				console.log('插入', data, '成功');
				deferred.resolve(res.insertedCount);
			}
		});
	}, function() {
		//不是一个数组，是单个文档，插入数据集合中
		table.insertOne(data, function(err, res) {
			if(err) {
				//插入失败
				console.log(err);
				deferred.reject();
			}
			else {
				//插入成功返回影响的行数
				console.log('插入', data, '成功');
				deferred.resolve(res.insertedCount);
			}
		});
	});
	return deferred.promise;
}

//mongodb数据库删除单条符合条件的数据函数
var remove = function(table, where) {
	var deferred = Q.defer();
	//选中数据集合（表）
	var table = this.collection(table);
	//删除单条符合where的数据
	table.deleteOne(where, function(err, res) {
		if(err) {
			//删除失败
			console.log(err);
			deferred.reject();
		}
		else {
			//删除成功返回影响的行数
			console.log('符合', where, '的一条数据已删除');
			deferred.resolve(res.deletedCount);
		}
	});
	return deferred.promise;
}

//mongodb数据库删除所有符合条件的数据函数
var removeAll = function(table, where) {
	var deferred = Q.defer();
	//选择数据集合（表）
	var table = this.collection(table);
	//删除所有符合where的数据
	table.deleteMany(where, function(err, res) {
		if(err) {
			//删除失败
			console.log(err);
			deferred.reject();
		}
		else {
			//删除成功并返回影响的行数
			console.log('符合', where, '的所有数据已删除');
			deferred.resolve(res.deletedCount);
		}
	});
	return deferred.promise;
}

//mongodb数据库查询符合条件的数据，where可以为空表示查询所有数据
var select = function(table, where) {
	var deferred = Q.defer();
	//判断是否设置了where值
	if(where) {
		//设置了where使用此条件查询
		var datas = this.collection(table).find(where);
	}
	else {
		//未设置where查询全部
		var datas = this.collection(table).find();
	}
	//将数据转换成包含对象的数组
	datas.toArray(function(err, data) {
		if(err) {
			//转换失败
			console.log(err);
			deferred.reject();
		}
		else {
			//转换成功返回数据
			console.log('符合', where, '条件的', data.length, '条数据已经查询并返回');
			deferred.resolve(data);
		}
	});
	return deferred.promise;
}

//mongodb数据库修改单条符合条件的数据函数
var update = function(table, where, setData) {
	var deferred = Q.defer();
	//选择数据集合（表）
	var table = this.collection(table);
	//修改单条符合where的数据
	table.updateOne(where, {$set: setData}, function(err, res) {
		if(err) {
			//修改失败
			console.log(err);
			deferred.reject();
		}
		else {
			//修改成功并返回影响的行数
			console.log('符合', where, '的' + res.matchedCount + '数据已修改');
			deferred.resolve(res.matchedCount);
		}
	})
	return deferred.promise;
}

//mongodb数据库修改所有符合条件的数据函数
var updateAll = function(table, where, setData) {
	var deferred = Q.defer();
	//选择数据集合（表）
	var table = this.collection(table);
	//修改所有符合where的数据
	table.updateMany(where, {$set: setData}, function(err, res) {
		if(err) {
			//修改失败
			console.log(err);
			deferred.reject();
		}
		else {
			//修改成功并返回影响的行数
			console.log('符合', where, '的' + res.matchedCount + '的数据已修改');
			deferred.resolve(res.matchedCount);
		}
	})
	return deferred.promise;
}

//嵌入到db实例中的函数列表
var dbFuns = {
	close: close,
	insert: insert,
	remove: remove,
	removeAll: removeAll,
	select: select,
	update: update,
	updateAll: updateAll
}

//暴露接口
module.exports = {
	connect: connect,
}
